#include "gt_search_util.h"

#include <cstdio>
#include <cstdlib>
#include <cstring>
#if __linux
#include <sys/stat.h>
#endif

#include "gt_util.h"

// ok
void resize_string(char **str, size_t *string_size, size_t minimal_size) {
  size_t str_len = strlen(*str);
  size_t new_size = *string_size;
  while (minimal_size >= new_size - str_len)
    new_size *= 2;

  if (new_size != *string_size) {
    *str = (char *)realloc(*str, new_size);
    *string_size = new_size;
  }
}

// ok
int validate_file(const char *path) {
  struct stat st;
  if (stat(path, &st) == 0 && S_ISREG(st.st_mode) == 1)
    return 1;

  return 0;
}

// ok
const char *apply_regex(const char *output, char *expr) {
  option_t *opt = (option_t *)calloc(1, sizeof(*opt));
  char *match = regex(opt, (char *)output, expr);
  free(opt);

  return match;
}

// ok
void popen_search(search_t *search, external_parser_t *parser) {
  char parser_args[PATH_MAX] = "";
  strcat(parser_args, parser->default_arguments);
  strcat(parser_args, search->option->parser_options);

  char command[PATH_MAX] = "";

  snprintf(command, sizeof(command),
           search->option->parser_cmd[search->option->search_type], parser_args,
           search->option->pattern, search->option->directory);

  FILE *fp = popen(command, "r");
  if (NULL == fp) {
    printf("Failed to run command: %s \n", command);
    exit(1);
  }

  size_t read_size;
  char *line;
  while (getline(&line, &read_size, fp) != -1) {
    char *eol = &line[strlen(line) - 1];
    if (*eol == '\n')
      *eol = '\0';

    if (parser->match_blank_line(search->result, line))
      continue;
    if (parser->match_file(search->result, line))
      continue;
    if (parser->match_line(search->result, line))
      continue;

    fprintf(stderr, "[ERROR]: unmatched output line:\n\t\"%s\"\n", line);
    abort();
    exit(-1);
  }

  free(line);

  pclose(fp);
}